// LogLeader.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


#include <gtkmm.h>

class CellItem_Bug
{
public:
    CellItem_Bug();
    CellItem_Bug(bool fixed, guint number, const Glib::ustring& severity, const Glib::ustring& description);
    CellItem_Bug(const CellItem_Bug& src);
    ~CellItem_Bug();
    CellItem_Bug& operator=(const CellItem_Bug& src);

    bool m_fixed;
    guint m_number;
    Glib::ustring m_severity;
    Glib::ustring m_description;
};

class Example_TreeView_ListStore : public Gtk::Window
{
public:
    Example_TreeView_ListStore();
    virtual ~Example_TreeView_ListStore();

protected:
    virtual void create_model();
    virtual void add_columns();
    virtual void add_items();
    virtual void liststore_add_item(const CellItem_Bug& foo);

    //Member widgets:
    Gtk::VBox m_VBox;
    Gtk::ScrolledWindow m_ScrolledWindow;
    Gtk::Label m_Label;
    Gtk::TreeView m_TreeView;
    Glib::RefPtr<Gtk::ListStore> m_refListStore;

    typedef std::vector<CellItem_Bug> type_vecItems;
    type_vecItems m_vecItems;

    struct ModelColumns : public Gtk::TreeModelColumnRecord
    {
        Gtk::TreeModelColumn<bool>          fixed;
        Gtk::TreeModelColumn<unsigned int>  number;
        Gtk::TreeModelColumn<Glib::ustring> severity;
        Gtk::TreeModelColumn<Glib::ustring> description;

        ModelColumns() { add(fixed); add(number); add(severity); add(description); }
    };

    const ModelColumns m_columns;
};


CellItem_Bug::CellItem_Bug()
{
    m_fixed = false;
    m_number = 0;
}

CellItem_Bug::CellItem_Bug(bool fixed, guint number, const Glib::ustring& severity, const Glib::ustring& description)
{
    m_fixed = fixed;
    m_number = number;
    m_severity = severity;
    m_description = description;
}

CellItem_Bug::CellItem_Bug(const CellItem_Bug& src)
{
    operator=(src);
}

CellItem_Bug::~CellItem_Bug()
{
}

CellItem_Bug& CellItem_Bug::operator=(const CellItem_Bug& src)
{
    m_fixed = src.m_fixed;
    m_number = src.m_number;
    m_severity = src.m_severity;
    m_description = src.m_description;

    return *this;
}


//Called by DemoWindow;
Gtk::Window* do_treeview_liststore()
{
    return new Example_TreeView_ListStore();
}


Example_TreeView_ListStore::Example_TreeView_ListStore()
  : m_VBox(false, 8),
    m_Label("This is the bug list (note: not based on real data, it would be nice to have a nice ODBC interface to bugzilla or so, though).")
{
    set_title("Gtk::ListStore demo");
    set_border_width(8);
    set_default_size(280, 250);

    add(m_VBox);
    m_VBox.pack_start(m_Label, Gtk::PACK_SHRINK);

    m_ScrolledWindow.set_shadow_type(Gtk::SHADOW_ETCHED_IN);
    m_ScrolledWindow.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
    m_VBox.pack_start(m_ScrolledWindow);

    /* create model */
    create_model();

    /* create tree view */
    m_TreeView.set_model(m_refListStore);
    m_TreeView.set_rules_hint();
    m_TreeView.set_search_column(m_columns.description.index());

    add_columns();
    m_ScrolledWindow.add(m_TreeView);

    show_all();
}

Example_TreeView_ListStore::~Example_TreeView_ListStore()
{
}

void Example_TreeView_ListStore::add_items()
{
    for( int i = 0; i < 500000; ++i){
        m_vecItems.push_back( CellItem_Bug(false, i, "Normal",     "scrollable notebooks and hidden tabs") );
    }
}

void Example_TreeView_ListStore::create_model()
{
    m_refListStore = Gtk::ListStore::create(m_columns);

    add_items();

    std::for_each(
        m_vecItems.begin(), m_vecItems.end(),
        sigc::mem_fun(*this, &Example_TreeView_ListStore::liststore_add_item));
}

void Example_TreeView_ListStore::liststore_add_item(const CellItem_Bug& foo)
{
    Gtk::TreeRow row = *(m_refListStore->append());

    row[m_columns.fixed]       = foo.m_fixed;
    row[m_columns.number]      = foo.m_number;
    row[m_columns.severity]    = foo.m_severity;
    row[m_columns.description] = foo.m_description;
}

void Example_TreeView_ListStore::add_columns()
{
    /* column for fixed toggles */
    {
        int cols_count = m_TreeView.append_column_editable("Fixed?", m_columns.fixed);
        Gtk::TreeViewColumn* pColumn = m_TreeView.get_column(cols_count-1);

        /* set this column to a fixed sizing (of 50 pixels) */
        pColumn->set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED);
        pColumn->set_fixed_width(50);
        pColumn->set_clickable();
    }

    /* column for bug numbers */
    m_TreeView.append_column("Bug number", m_columns.number);

    /* column for severities */
    m_TreeView.append_column("Severity", m_columns.severity);

    /* column for descriptions */
    m_TreeView.append_column("Description", m_columns.description);
}

int main(int argc, char *argv[])
{
    Gtk::Main kit(argc, argv);

    Example_TreeView_ListStore window;
    //Shows the window and returns when it is closed.
    Gtk::Main::run(window);

    return 0;
}
